package com.compunit.composite.core;

import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import com.compunit.composite.core.cx.enumn.EConfigurationTag;
import com.compunit.composite.core.cx.enumn.EPropertiesTag;
import com.compunit.composite.core.cx.enumn.EPropertyTag;
import com.compunit.composite.core.interfaces.IConfigurationImporter;
import com.compunit.composite.core.interfaces.xml.IXMLParser;
import com.compunit.composite.core.interfaces.xml.IXMLTag;
import com.compunit.composite.core.xml.XMLParser;

/**
 * <code>ConfigurationImporter</code> defines implementation
 * of the utility configuration importer.
 *
 * @author Yi Wang (Neakor)
 * @version Creation date: 12-05-2009 15:25 EST
 * @version Modified date: 12-05-2009 15:32 EST
 */
public class ConfigurationImporter implements IConfigurationImporter {
	/**
	 * The <code>IXMLParser</code>.
	 */
	private final IXMLParser parser;
	/**
	 * The <code>Map</code> of <code>String</code> fully
	 * qualified class name of components to associated
	 * <code>Properties</code> data. 
	 */
	private final Map<String, Properties> cache;
	
	/**
	 * Constructor of <code>ConfigurationImporter</code>.
	 */
	public ConfigurationImporter() {
		this.parser = new XMLParser();
		this.cache = new HashMap<String, Properties>(5);
	}

	@Override
	public void process(final URL file) throws IOException {
		if(file == null) throw new IOException("Missing configuration file");
		// Initialize parser and loader.
		this.cleanup();
		this.parser.process(file);
		// Retrieve data from configuration file.
		final IXMLTag root = this.parser.getRoot();
		if(!root.getName().equals(EConfigurationTag.Name.getString())) throw new IllegalArgumentException("Invalid configuration file.");
		for(final IXMLTag pstag : root.getChildren()) {
			if(!pstag.getName().equals(EPropertiesTag.Name.getString())) continue;
			final String classname = pstag.getValue(EPropertiesTag.Classname.getString());
			final Properties properties = new Properties();
			// Individual properties.
			for(final IXMLTag ptag : pstag.getChildren()) {
				if(!ptag.getName().equals(EPropertyTag.Name.getString())) continue;
				final String key = ptag.getValue(EPropertyTag.Key_PropertyKey.getString());
				final String value = ptag.getValue(EPropertyTag.Key_PropertyValue.getString());
				properties.setProperty(key, value);
			}
			// Put into cache.
			this.cache.put(classname, properties);
		}
	}

	@Override
	public Properties get(final String classname) {
		return this.cache.get(classname);
	}

	@Override
	public void cleanup() {
		this.parser.cleanup();
		this.cache.clear();
	}
}
